package org.example;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferUShort;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.*;

public class CC_FileOutPut2 {

    public static void main(String[] args) throws IOException {
        String inputPngPath = "D:\\Documents\\workspaces\\Gitee\\java-projects\\untitled\\src\\main\\resources\\ame\\Snipaste.png";
        String outputRawPath = "output.raw";
        String outputPngPath = "output.png";

        // 步骤1: 读取PNG图片
        BufferedImage pngImage = ImageIO.read(new File(inputPngPath));

        // 步骤2: 转换PNG到灰度
        BufferedImage grayscaleImage = convertToGrayscale(pngImage);

        // 步骤3: 转换灰度图像到16位RAW
        convertToRaw16Grayscale(grayscaleImage, outputRawPath);

        // 步骤4: 读取RAW文件
        byte[] rawImageData = readRawFile(outputRawPath, grayscaleImage.getWidth(), grayscaleImage.getHeight());

        // 步骤5: 转换RAW数据回灰度图像
        BufferedImage rawGrayscaleImage = convertFromRaw16Grayscale(rawImageData, grayscaleImage.getWidth(), grayscaleImage.getHeight());

        // 步骤6: 转换灰度图像回PNG数据
        byte[] pngData = convertToPngData(rawGrayscaleImage);

        // 打印PNG数据长度，实际应用中可以将其写入文件或通过网络传输
        System.out.println("PNG数据长度: " + pngData.length);
    }

    private static BufferedImage convertToGrayscale(BufferedImage image) {
        // 创建灰度图像
        BufferedImage grayscaleImage = new BufferedImage(
                image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
        grayscaleImage.getGraphics().drawImage(image, 0, 0, null);
        return grayscaleImage;
    }

    private static void convertToRaw16Grayscale(BufferedImage image, String outputPath) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(outputPath)) {
            byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
            for (int i = 0; i < pixels.length; i++) {
                // 将8位灰度值扩展到16位
                int gray16 = pixels[i] & 0xFF;
                fos.write((gray16 << 8) & 0xFF00);
                fos.write(gray16 & 0xFF);
            }
        }
    }

    private static byte[] readRawFile(String path, int width, int height) throws IOException {
        byte[] rawData = new byte[width * height * 2];
        try (FileInputStream fis = new FileInputStream(path)) {
            int bytesRead = fis.read(rawData);
            if (bytesRead != width * height * 2) {
                throw new IOException("读取的RAW数据不完整.");
            }
        }
        return rawData;
    }

    private static BufferedImage convertFromRaw16Grayscale(byte[] rawData, int width, int height) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        WritableRaster raster = image.getRaster();
        DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
        byte[] pixels = dataBuffer.getData();
        int index = 0;
        for (int i = 0; i < pixels.length; i++) {
            // 从RAW数据中读取16位灰度值，并转换为8位
            pixels[i] = (byte) ((rawData[index] << 8) | (rawData[index + 1] & 0xFF));
            index += 2;
        }
        return image;
    }

    private static byte[] convertToPngData(BufferedImage image) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            ImageIO.write(image, "png", bos);
            return bos.toByteArray();
        } catch (IOException e) {
            throw new IOException("PNG数据转换失败.", e);
        }
    }
}
